package com.java.es.pojo;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author jiangli
 * @date 2019/11/20 22:40
 * 手写spring ioc实现: 反射 + dom4j
 */
public class SpringIOC {
	private String xmlPath;

	public SpringIOC(String xmlPath) {
		this.xmlPath = xmlPath;
	}

	public static void main(String[] args) throws Exception{
		SpringIOC ctx = new SpringIOC("user.xml");
		List<Object> bean = ctx.getBean();
		for (Object o : bean) {
			UserEntity user = (UserEntity) o;
			System.out.println(user.getUserId() + "----" + user.getUserName());
		}
	}

	private List<Object> getBean() throws Exception{
		// spring 加载过程 或者spring ioc实现原理
		// 1.读取xml配置文件
		// 获取xml解析器
		SAXReader saxReader = new SAXReader();
		// this.getClass().getClassLoader().getResourceAsStream("xmlPath")
		// 获取当前项目路径
		Document document = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
		// 获取跟节点对象
		Element root = document.getRootElement();
		// 获取所有子节点
		List<Element> elements = root.elements();
		List<Object> objects = new ArrayList<>();
		for (Element element : elements) {
			//使用反射创建bean
			String className = element.attributeValue("class");
			Class<?> forName = Class.forName(className);
			Object object = forName.newInstance();
			// 取所有成员属性
			List<Element> filedElements = element.elements();
			for (Element filedElement : filedElements) {
				//为属性赋值
				String name = filedElement.attributeValue("name");
				String value = filedElement.attributeValue("value");
				Field declaredField = forName.getDeclaredField(name);
				//y允许为私有成员赋值
				declaredField.setAccessible(true);
				declaredField.set(object, value);
			}
			objects.add(object);
		}
		return objects;
	}
}
